package com.douqu.game.battle.entity;

import com.bean.core.util.TimeUtils;
import com.douqu.game.battle.entity.aobject.BattleAObject;
import com.douqu.game.battle.util.BattleUtils;
import com.douqu.game.battle.util.MsgUtils;
import com.douqu.game.core.config.battle.BuffConfig;
import com.douqu.game.core.factory.ConstantFactory;
import com.douqu.game.core.factory.DataFactory;
import com.douqu.game.core.protobuf.SGCommonProto;
import com.douqu.game.core.util.LogUtils;

import java.util.List;

/**
 * @Author: Bean
 * @Description:
 * @Date: 2017-10-11 18:48
 */
public class BattleBuff {


    /**
     * 唯一ID
     */
    public long id;

    public int skillId;

    public BuffConfig buffConfig;

    /** BUFF释放者 */
    public BattleAObject releaser;

    /** BUFF在哪个身上 */
    public BattleAObject master;

    /**
     * 剩余时间
     */
    public long endTime;

    /***
     * 当前叠加层数
     */
    public int curOverlayer;

    /**
     * 增加的值
     */
    public int onceValue;

    public long updateTime;

    public String skillKey;


    public BattleBuff(BuffConfig buffConfig, BattleAObject releaser, BattleAObject master, int skillId, String skillKey)
    {
        this.id = master.getUniqueId() * 10000000000l + releaser.getUniqueId() * 1000000l + buffConfig.id;
        this.skillId = skillId;
        this.buffConfig = buffConfig;
        this.endTime = DataFactory.currentTime + buffConfig.effectTime;
        this.releaser = releaser;
        this.master = master;
//        this.skillKey = skillKey;//BUFF不要
        this.skillKey = "";
        if(buffConfig.initOverlay == ConstantFactory.BUFF_INIT_OVERLAY_ENEMY)
            this.curOverlayer = releaser.masterController.getAttachment().getTargetBattleTmp().getSoldierList().size();
        else if(buffConfig.initOverlay == ConstantFactory.BUFF_INIT_OVERLAY_PARTNER)
            this.curOverlayer = releaser.masterController.getAttachment().getSoldierList().size();
        else if(buffConfig.initOverlay == ConstantFactory.BUFF_INIT_OVERLAY_ALL)
            this.curOverlayer = releaser.masterController.getAttachment().getSoldierList().size() + releaser.masterController.getAttachment().getTargetBattleTmp().getSoldierList().size();
        else
            this.curOverlayer = 1;

        if(endTime > DataFactory.currentTime)
        {
            //计算每次要增加或减少多少值 参考属性 * BUFF系数 + BUFF基础值
            if(buffConfig.referTarget == ConstantFactory.BUFF_REFER_RELEASE)//参考释放者的属性
                onceValue = (int) (releaser.getBaseAtt(buffConfig.referValue) * buffConfig.coefficient) + buffConfig.effectValue;
            else if(buffConfig.referTarget == ConstantFactory.BUFF_REFER_MASTER)//参考持有者的属性
                onceValue = (int) (master.getBaseAtt(buffConfig.referValue) * buffConfig.coefficient) + buffConfig.effectValue;
        }

        LogUtils.debug("新增BUFF" + buffConfig.getName() + " 结束时间: " + TimeUtils.getFormatTime(endTime) + " onceValue -> " + onceValue + " endTime:" + endTime + "  coefficient:" + buffConfig.coefficient + "  master.getBaseAtt(buffConfig.referValue):" + master.getBaseAtt(buffConfig.referValue) + "  effectValue:" + buffConfig.effectValue);
    }



    public void update(long currentTime)
    {
        if(updateTime > 0)
        {
            if(currentTime - updateTime < ConstantFactory.UPDATE_BATTLE_BUFF_TIME)
                return;
        }

        int addValue = 0;
        if(buffConfig.effectType == ConstantFactory.BUFF_TYPE_ADD_HP)
        {
            addValue = onceValue * curOverlayer;
        }
        else if(buffConfig.effectType == ConstantFactory.BUFF_TYPE_SUB_HP)
        {
            addValue = -onceValue * curOverlayer;
        }
        if(addValue != 0)
        {
            if(buffConfig.effectRange[0] == ConstantFactory.BUFF_RANGE_TYPE_SINGLE)
            {
                long result = master.addHP(addValue);
                if(addValue < 0)
                    releaser.addDamage(Math.abs(result));

                if(result != 0)
                {
                    LogUtils.debug("BUFF血变化:" + addValue + "  master:" + master + " releaser:" + releaser);

                    MsgUtils.sendDamage(master.battleController, releaser.getUniqueId(), releaser.getConfigId(), skillId, master.getUniqueId(), addValue, master.getHp(),
                            SGCommonProto.E_DAMAGE_TYPE.DAMAGE_TYPE_DEFAULT, buffConfig.id, skillKey);
                }
            }
            else if(buffConfig.effectRange[0] == ConstantFactory.BUFF_RANGE_TYPE_CIRCLE)
            {
                List<BattleAObject> targets = master.battleController.getTargetsByGroup(buffConfig.effectRange[2], master.masterController.getAttachment());
                for(BattleAObject battleAObject : targets)
                {
                    if(BattleUtils.isInCircleRange(master.position, battleAObject.position, buffConfig.effectRange[1]))
                    {
                        long result = battleAObject.addHP(addValue);
                        if(addValue < 0)
                            releaser.addDamage(Math.abs(result));

                        if(result != 0)
                        {
                            LogUtils.debug("BUFF血变化:" + addValue + "  master:" + battleAObject);

                            MsgUtils.sendDamage(battleAObject.battleController, releaser.getUniqueId(), releaser.getConfigId(), skillId, battleAObject.getUniqueId(), addValue, battleAObject.getHp(),
                                    SGCommonProto.E_DAMAGE_TYPE.DAMAGE_TYPE_DEFAULT, buffConfig.id, skillKey);
                        }

                    }
                }
            }
        }

//        surplusTime -= ConstantFactory.UPDATE_BATTLE_BUFF_TIME;
//        surplusTime = surplusTime < 0 ? 0 : surplusTime;
//        int surplusTime = getSurplusTime();
//        curOverlayer = surplusTime%buffConfig.effectTime == 0 ? surplusTime/buffConfig.effectTime : surplusTime/buffConfig.effectTime + 1;

        updateTime = currentTime;
    }

    /**
     * 是否一直有效
     * @return
     */
    public boolean isForever()
    {
        return buffConfig.effectTime == 0;
    }


    public boolean isEnd()
    {
        if(isForever())
            return false;

        return DataFactory.currentTime >= endTime;
    }





    public SGCommonProto.BuffChange.Builder parseBuffChange(SGCommonProto.E_BUFFCHANGE_TYPE changeType)
    {
        SGCommonProto.BuffChange.Builder data = SGCommonProto.BuffChange.newBuilder();
        data.setChangeType(changeType);
        data.setUniqueId(id);
        data.setLayerCount(curOverlayer);
        data.setRemainTime(getSurplusTime());
        return data;
    }

    public int getSurplusTime()
    {
        if(endTime < DataFactory.currentTime)
            return 0;

        return (int) (endTime - DataFactory.currentTime);
    }

    public int getType()
    {
        return buffConfig.effectType;
    }

    public int getBuffId()
    {
        return buffConfig.id;
    }


    @Override
    public String toString() {
        return "BattleBuff{" +
                "id=" + id +
                ", buff=" + buffConfig +
                ", onceValue=" + onceValue +
                ", curOverlayer=" + curOverlayer +
                ", endTime=" + endTime +
                ", updateTime=" + updateTime +
                '}';
    }
}
